package com.candy.dao;

import java.sql.*;
import java.util.LinkedHashMap;
import java.util.LinkedList;

/**
 *PreparedStatement的封装
 */
public class DBDriver {

    /**
     * 获取数据库的链接对象
     * @return 数据库链接对象
     */
    public static Connection getConn(){
        Connection conn =null;
//        （1）注册或实例化jdbc的驱动类
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            //    （2）获取数据库连接对象Connection
//            jdbc:mysql表示使用jdbc链接mysql数据库
//            localhost表示要链接的数据库所在的地址（ip），此时的localhost表示本机，可以用127.0.0.1代替
//            3306是mysql数据库的端口号
//            database_name表示你要链接的数据库的名字
            String url = "jdbc:mysql://localhost:3306/ld_mysql0317? characterEncoding=utf8 & useSSL=false & serverTimezone=UTC & rewriteBatchedStatements=true";
            String username = "root";
            String password = "123456";
            conn = DriverManager.getConnection(url, username, password);
        }catch (Exception e){

        }
        return  conn;
    }

    /**
     * 查询操作
     * @param sql 预编译的SQL
     * @param obj 要传递的参数，可以是0个或n个
     * @return 根据SQL执行后的查询结果
     */
    public static LinkedList<LinkedHashMap<String,Object>> query4ListMap(String sql,Object ...obj){
        LinkedList<LinkedHashMap<String,Object>> lp=null;
//        把Connection\Statement\ResultSet放在try后面的括号中，使用完毕后，方法会自动执行close方法
//        前提是，你需要关闭的对象继承自AutoCloseable
        try{
                Connection conn=getConn();
                //获取数据库操作对象Statement（执行增删改查）
                PreparedStatement ment= conn.prepareStatement(sql);
//              任意个参数会最终打包为一个数组，在这里我们可以直接对数据进行遍历，完成参数赋值的操作
            for (int i = 0; i < obj.length; i++) {
                ment.setObject(i+1, obj[i]);
            }
//        执行参数给定的sql获取查询结果集
                ResultSet re= ment.executeQuery();
            //    解析结果集对象ResultSet，进行相关的业务处理；
//            当前行有数据则返回true，反之返回false
//            为了解决资源关闭后无法获取数据的问题，这里需要对数据进行转储
//            常见的数据转储的方式有两种，第一种：List+Map；第二种是List+JavaBean
//            准备容器，这里采用List+Map的方式进行转储
            lp=new LinkedList();
//            准备好一个map，存储每一行的数据
            LinkedHashMap eachRow=null;
//            这里需要知道表中一个有多少个列，每个列的列名是什么，方便后续进行存放在map中
//            获取元数据（能够知道数据的结构组成）
            ResultSetMetaData rm=re.getMetaData();
//            获取数据表中一共有多少个列
            int count=rm.getColumnCount();
            while (re.next()){
                eachRow=new LinkedHashMap();
                //               循环取出数据，并将数据存储在map中
                for (int i = 1; i <=count ; i++) {
                    //                    rm.getColumnName(i)取出该列对应的列名
                    //                    re.getObject(i)：通过该列的索引取出该列对应值
                    eachRow.put(rm.getColumnName(i),re.getObject(i));
                }
                //               将每一行数据存放在list集合中
                lp.add(eachRow);
            }
//            关闭资源
            re.close();
            ment.close();
            conn.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return lp;
    }

    /**
     * 增删改操作的封装
     * @param sql 要执行的预编译的SQL
     * @param objs 任意个参数，可以是0个或n个
     * @return 影响行数
     */
    public static int update(String sql,Object ... objs){
        int num= 0;
        try(Connection conn=getConn();
            PreparedStatement statement=conn.prepareStatement(sql);) {
//            对占位的参数循环赋值
            for (int i = 0; i < objs.length ; i++) {
                statement.setObject(i+1, objs[i]);
            }
            num=statement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return num;

    }
}

